package jnzb.model.nzb;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * Top level NZB class representing an NZB file
 * 
 * @author AA1
 * 
 */
public class NZB implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private List<File> files;

	private String filename;
	private String path;
	private long size;

	private transient boolean allAttempted = false;

	public int getNumberOfFiles() {
		return files.size();
	}

	public List<File> getFiles() {
		return files;
	}

	public void setFiles(List<File> files) {
		this.files = files;
	}

	public String getFilename() {
		return filename;
	}

	public void setFilename(String filename) {
		this.filename = filename;
	}

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	/**
	 * This excludes files we're ignoring
	 * 
	 * @return
	 */
	public long getSize() {
		if (this.size == 0) {
			Iterator<File> f = files.iterator();
			while (f.hasNext()) {
				File file = f.next();
				if (!file.isIgnore()) {
					size += file.getSize();
				}
			}
		}
		return this.size;

	}

	/**
	 * Indicates if all the files have been decoded - therefore we're done
	 * 
	 * @return true if all decoded
	 */
	public boolean allDecoded() {
		boolean allDecoded = true;
		Iterator<File> f = files.iterator();
		while (f.hasNext()) {
			File file = f.next();
			allDecoded &= (file.isDecoded() || file.isIgnore());
		}
		return allDecoded;

	}

	
	/**
	 * Works out how many seconds there are left until this NZB is downloaded
	 * based on a speed
	 * 
	 * @return
	 */
	public int getTimeLeftAt(double avg) {

		// Work out how many bytes left to go
		long bytesLeft = 0;
		Iterator<File> f = files.iterator();
		while (f.hasNext()) {
			File file = f.next();
			// Only include imcomplete downloads we are not ignoring
			if (!file.allSegmentsDownloaded() && !file.isIgnore()) {
				bytesLeft += file.getBytesRemaining();
			}
		}

		// Number of k left to go
		double kLeft = bytesLeft / 1024;

		// Number of seconds left to download number of k left, using average
		// k/s - use a long cos we're not interested in fractions of a second
		return (int) (kLeft / avg);
	}

	/**
	 * Returns a string that will be displayed in the waiting queue
	 * 
	 * @return
	 */
	public Object getQueueDetail() {
		return this.filename;
	}

	/**
	 * Indicates if this NZB has been completely thro the downloader, or we've
	 * aborted it's download this session
	 * 
	 * @return
	 */
	public boolean getAllAttempted() {
		return this.allAttempted;
	}

	public void setAllAttempted(boolean attempted) {
		this.allAttempted = attempted;
	}

	/**
	 * Returns the number of bytes downloaded of this nzb
	 * 
	 * @return
	 */
	public long getProgress() {
		long totalProgress = 0;
		Iterator<File> f = files.iterator();
		while (f.hasNext()) {
			File file = f.next();
			if (!file.isIgnore()) {
				totalProgress += file.getProgress();
			}
		}
		return totalProgress;
	}

	/**
	 * Get the current progress through the NZB as a percentage
	 * 
	 * @return
	 */
	public double getProgressAsPercentage() {
		return (100.0 / this.getSize()) * this.getProgress();
	}

}
